use crate::error::Result;
use crate::models::{CrawledData, CrawlerConfig, CrawlerStatus};
use parking_lot::RwLock;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::mpsc;
use tokio::time::sleep;

pub struct CrawlerEngine {
    status: Arc<RwLock<CrawlerStatus>>,
    #[allow(dead_code)]
    config: Arc<RwLock<Option<CrawlerConfig>>>,
    stop_signal: Arc<RwLock<bool>>,
    python_process: Arc<RwLock<Option<tokio::process::Child>>>,
}

impl CrawlerEngine {
    #[allow(dead_code)]
    pub fn new(config: CrawlerConfig) -> Self {
        Self {
            status: Arc::new(RwLock::new(CrawlerStatus::default())),
            config: Arc::new(RwLock::new(Some(config))),
            stop_signal: Arc::new(RwLock::new(false)),
            python_process: Arc::new(RwLock::new(None)),
        }
    }
    
    pub fn new_with_process(process: tokio::process::Child) -> Self {
        let mut status = CrawlerStatus::default();
        status.is_running = true;
        status.current_task = "知乎爬虫".to_string();
        
        Self {
            status: Arc::new(RwLock::new(status)),
            config: Arc::new(RwLock::new(None)),
            stop_signal: Arc::new(RwLock::new(false)),
            python_process: Arc::new(RwLock::new(Some(process))),
        }
    }
    
    pub fn get_status(&self) -> CrawlerStatus {
        self.status.read().clone()
    }
    
    #[allow(dead_code)]
    pub fn update_config(&self, config: CrawlerConfig) {
        *self.config.write() = Some(config);
    }
    
    #[allow(dead_code)]
    pub async fn start(&self) -> Result<mpsc::Receiver<CrawledData>> {
        let (tx, rx) = mpsc::channel(1000);
        
        // 更新状态
        {
            let mut status = self.status.write();
            status.is_running = true;
            status.is_paused = false;
            status.progress = 0.0;
            status.crawled_count = 0;
            status.success_count = 0;
            status.failed_count = 0;
            status.skipped_count = 0;
        }
        
        // 重置停止信号
        *self.stop_signal.write() = false;
        
        let status = Arc::clone(&self.status);
        let config = Arc::clone(&self.config);
        let stop_signal = Arc::clone(&self.stop_signal);
        
        // 启动爬虫任务
        tokio::spawn(async move {
            let start_time = Instant::now();
            let config_opt = config.read().clone();
            
            if let Some(config) = config_opt {
                // 更新当前任务信息
                {
                    let mut status = status.write();
                    status.current_task = format!(
                        "{}-{}",
                        Self::get_platform_name(&config.platform),
                        config.keywords.split(',').next().unwrap_or("搜索")
                    );
                }
                
                // 模拟爬取过程
                for i in 0..config.crawl_count {
                    // 检查停止信号
                    if *stop_signal.read() {
                        break;
                    }
                    
                    // 检查暂停状态
                    while status.read().is_paused && !*stop_signal.read() {
                        sleep(Duration::from_millis(100)).await;
                    }
                    
                    // 模拟爬取数据
                    let data = Self::simulate_crawl_data(&config, i).await;
                    
                    // 发送数据
                    if tx.send(data).await.is_err() {
                        break;
                    }
                    
                    // 更新状态
                    {
                        let mut status = status.write();
                        status.crawled_count = i + 1;
                        status.progress = ((i + 1) as f64 / config.crawl_count as f64) * 100.0;
                        
                        // 模拟成功/失败统计
                        if i % 20 == 0 {
                            status.failed_count += 1;
                        } else if i % 50 == 0 {
                            status.skipped_count += 1;
                        } else {
                            status.success_count += 1;
                        }
                        
                        // 计算速度
                        let elapsed = start_time.elapsed().as_secs_f64();
                        if elapsed > 0.0 {
                            status.speed = (status.crawled_count as f64) / (elapsed / 60.0);
                        }
                        
                        // 更新时间
                        status.elapsed_time = Self::format_duration(elapsed);
                        if status.speed > 0.0 {
                            let remaining = (config.crawl_count - status.crawled_count) as f64 / status.speed * 60.0;
                            status.estimated_time = Self::format_duration(remaining);
                        }
                    }
                    
                    // 模拟延时
                    sleep(Duration::from_millis(500)).await;
                }
                
                // 完成任务
                {
                    let mut status = status.write();
                    status.is_running = false;
                    status.is_paused = false;
                    status.progress = 100.0;
                }
            }
        });
        
        Ok(rx)
    }
    
    pub fn pause(&self) {
        let mut status = self.status.write();
        status.is_paused = true;
        // TODO: 向Python进程发送暂停信号
    }
    
    #[allow(dead_code)]
    pub fn resume(&self) {
        let mut status = self.status.write();
        status.is_paused = false;
        // TODO: 向Python进程发送恢复信号
    }
    
    pub fn stop(&self) {
        *self.stop_signal.write() = true;
        let mut status = self.status.write();
        status.is_running = false;
        status.is_paused = false;
        
        // 终止Python进程
        if let Some(mut process) = self.python_process.write().take() {
            let _ = process.kill();
        }
    }
    
    /// 检查Python进程是否还活着
    pub fn is_process_alive(&self) -> bool {
        if let Some(process) = self.python_process.read().as_ref() {
            match process.id() {
                Some(pid) => {
                    // 在Windows上检查进程是否存在
                    #[cfg(target_os = "windows")]
                    {
                        use std::process::Command;
                        let output = Command::new("tasklist")
                            .args(&["/FI", &format!("PID eq {}", pid)])
                            .output();
                        
                        match output {
                            Ok(output) => {
                                let output_str = String::from_utf8_lossy(&output.stdout);
                                output_str.contains(&pid.to_string())
                            }
                            Err(_) => false
                        }
                    }
                    
                    #[cfg(not(target_os = "windows"))]
                    {
                        // Unix系统上的进程检查
                        std::path::Path::new(&format!("/proc/{}", pid)).exists()
                    }
                }
                None => false
            }
        } else {
            false
        }
    }
    
    // 检查Python进程状态
    #[allow(dead_code)]
    pub async fn check_process_status(&self) {
        if let Some(process) = self.python_process.write().as_mut() {
            match process.try_wait() {
                Ok(Some(exit_status)) => {
                    // 进程已结束
                    let mut status = self.status.write();
                    status.is_running = false;
                    status.is_paused = false;
                    
                    if exit_status.success() {
                        status.progress = 100.0;
                    }
                }
                Ok(None) => {
                    // 进程仍在运行
                    // 可以在这里读取进程输出来更新状态
                }
                Err(_) => {
                    // 检查状态时出错
                    let mut status = self.status.write();
                    status.is_running = false;
                }
            }
        }
    }
    
    #[allow(dead_code)]
    async fn simulate_crawl_data(config: &CrawlerConfig, index: i32) -> CrawledData {
        let mut data = CrawledData::new(&config.platform, "post");
        
        data.title = format!("模拟数据 {} - {}", index + 1, config.keywords.split(',').next().unwrap_or("默认"));
        data.content = Some(format!("这是第 {} 条模拟爬取的数据内容，关键词：{}", index + 1, config.keywords));
        data.author = format!("用户{}", index % 100 + 1);
        data.author_id = format!("user_{}", index % 100 + 1);
        data.url = format!("https://example.com/post/{}", index + 1);
        data.like_count = (index % 200) + 10;
        data.comment_count = (index % 50) + 1;
        data.share_count = index % 20;
        data.view_count = (index % 1000) + 100;
        data.keywords = config.keywords.clone();
        
        data
    }
    
    #[allow(dead_code)]
    fn get_platform_name(platform: &str) -> &str {
        match platform {
            "xhs" => "小红书",
            "douyin" => "抖音",
            "kuaishou" => "快手",
            "bilibili" => "B站",
            "weibo" => "微博",
            "zhihu" => "知乎",
            "tieba" => "贴吧",
            _ => platform,
        }
    }
    
    #[allow(dead_code)]
    fn format_duration(seconds: f64) -> String {
        let hours = (seconds / 3600.0) as u32;
        let minutes = ((seconds % 3600.0) / 60.0) as u32;
        let secs = (seconds % 60.0) as u32;
        
        if hours > 0 {
            format!("{:02}:{:02}:{:02}", hours, minutes, secs)
        } else {
            format!("{:02}:{:02}", minutes, secs)
        }
    }
}